<template>
  <div class="spectrum-container">
    <div id="spectrum" />
    <div id="marker">
      <svg version="1.1" width="24" height="322">
        <path
          fill="#aeadad"
          d="M 0 322 L 24 322  L 12 298 Z M 12 298 L 12 0"
          stroke="#aeadad"
          stroke-width="1"
        />
        <text x="7" y="319" fill="rgba(1, 23, 13, 1)">1</text>
      </svg>
    </div>
    <div v-if="markerPoints.length > 0" class="markers-info">
      <div class="markers-title">
        <span style="width: 36px;">Mark</span>
        <span style="width: 75px;">频率({{ speUnit }})</span>
        <span>幅度(dbuV/m)</span>
      </div>
      <div v-for="item in markerPoints" :key="item.index" class="markers-list">
        <span style="width: 36px;">{{ item.index }}</span>
        <span>{{ indexToPlot(item.point.x) }}</span>
        <span>{{ round(item.point.y, 3) }}</span>
      </div>
    </div>
    <div v-if="instance && instance.activeMarker" class="marker-values">
      <span v-for="item in currentValues" :key="item.label">{{ item.label + ':' + item.value }}</span>
    </div>
  </div>
</template>

<script setup>
import Highcharts from '@/plugins/highcharts'
import useScanStore from '@/store/modules/scanMonitor'
import SpectrumMarker from '@/common/classes/spectrumMark'
import TopMarker from '@/common/classes/topMarker'
import { round } from 'lodash'
import { numToPlot, indexToPlot } from '@/utils/utils'
import { chartConfig } from './chartConfig'
import { setInstance } from '@/utils/instance'

const props = defineProps({
  showLines: {
    type: Array,
    default: () => []
  },
  selectedFremarkers: {
    type: Array,
    default: () => []
  },
  isActive: {
    type: Boolean,
    default: true
  },
  isTopFollow: {
    type: Boolean,
    default: true
  },
  dataList: {
    type: Object,
    default: () => ({})
  }
})
const { dataList } = toRefs(props)
const instance = ref(null)
const markerPoints = ref([])
const scanStore = useScanStore()
const speUnit = computed(() => {
  const { centerFreqIn } = scanStore.spectrum
  if (centerFreqIn < 1000) {
    return numToPlot(centerFreqIn).slice(-2)
  }
  return numToPlot(centerFreqIn).slice(-3)
})
const currentValues = computed(() => {
  const x = instance.value.activeMarker.point.x
  return [
    { label: '频率', value: indexToPlot(x) },
    { label: '幅度值', value: round(dataList.value.current[x], 3) },
    { label: '门限值', value: round(dataList.value.limit[0],3) },
    { label: '最大值', value: round(dataList.value.max[x],3) },
    { label: '平均值', value: round(dataList.value.average[x],3) },
    { label: '最小值', value: round(dataList.value.min[x],3) },
  ]
})
const initHighChart = () => {
  instance.value = new Highcharts.Chart('spectrum', chartConfig)
  setInstance(markRaw(instance.value))
}
const getXlabelFormat = (showNum, spectrum) => {
  const left = spectrum.centerFreqIn - spectrum.scanWidth / 2
  return function () {
    const val = (this.value / (showNum - 1)) * spectrum.scanWidth + left
    return numToPlot(val)
  }
}
const getXAisConfig = (showNum, spectrum) => {
  const axis = chartConfig.xAxis
  axis.max = showNum - 1
  axis.min = 0
  axis.tickAmount = 11
  axis.tickInterval = (showNum - 1) / 10
  axis.labels.formatter = getXlabelFormat(showNum, spectrum)
  return axis
}
const updateChartConfig = (config) => {
  instance.value?.update(config)
}
const updateViewLines = (val) => {
  instance.value.series.forEach(item => {
    if (val.includes(item.name)) {
      item.setVisible(true)
    } else {
      item.setVisible(false)
    }
  })
}
const updateSpectrumMark = (items) => {
  const markers = instance.value.specturmMarkers || []
  markerPoints.value = []
  markers.forEach(mk => mk.visible && mk.hide())
  if (!props.isActive) {
    return
  }
  items.forEach(item => {
    let marker = markers.find(mk => mk.index === item)
    if (marker) {
      marker.show()
    } else {
      marker = new SpectrumMarker(instance.value, item, document.getElementById('marker'))
    }
    markerPoints.value.push(marker)
  })
  props.isTopFollow && markerPoints.value.push(instance.value.topMarker)
}
defineExpose({
  instance
})

watch(() => props.showLines, (val) => updateViewLines(val))
watch(() => props.selectedFremarkers, (val) => updateSpectrumMark(val))
watch(() => props.isActive, () => updateSpectrumMark(props.selectedFremarkers))
watch(() => props.isTopFollow, (val) => {
  if (!instance.value.topMarker) {
    new TopMarker(instance.value)
  }
  instance.value.topMarker.setVisible(val)
})
watch(() => props.dataList.current, val => {
  const dataLen = dataList.value.current.length
  if (dataLen !== scanStore.resultLen) {
    updateChartConfig({ xAxis: getXAisConfig(dataLen, scanStore.spectrum) })
    scanStore.resultLen = dataLen
  }
  instance.value.series.forEach((s, i) => {
    s.setData(dataList.value[s.options.id])
  })
})
watch(() => scanStore.spectrum.refLevel, val => {
  const yAxis = chartConfig.yAxis
  yAxis.max = val * 1
  yAxis.min = val - 100
  updateChartConfig({ yAxis })
})


onMounted(() => {
  initHighChart()
})
</script>

<style scoped lang="scss">
.spectrum-container {
  position: relative;
  height: 400px;
}

#spectrum {
  height: 100%;
}

#marker {
  position: absolute;
  bottom: 48px;
  cursor: pointer;
  display: none;
  opacity: 0.6;
}

.markers-info {
  font-size: 12px;
  color: var(--scan-text-color);
  position: absolute;
  right: 0;
  top: 12px;

  span {
    padding: 0 6px;
    display: inline-block;
  }
}

.marker-values {
  font-size: 12px;
  color: var(--scan-text-color);
  position: absolute;
  left: 60px;
  top: 12px;
  width: 300px;

  span {
    padding: 0 6px;
    display: inline-block;

    &:nth-child(4),
    &:nth-child(1) {
      width: 106px;
    }
  }
}
</style>